<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>富文本编辑器 + 删除控制</title>
    <style>
      .toolbar {
        border: 1px solid #ccc;
        padding: 5px;
        background-color: #f7f7f7;
      }
      .toolbar button {
        margin-right: 5px;
      }
      #editor {
        border: 1px solid #ccc;
        min-height: 200px;
        padding: 5px;
        background-color: #fff;
        margin-top: 10px;
      }
    </style>
  </head>
  <body>
    <div class="toolbar">
		<button onclick="setParam()">
		  参数
		</button>
		<button onclick="document.execCommand('bold', true, null);">
		  加粗
		</button>
		<button onclick="document.execCommand('italic', false, null);" >
		  斜体
		</button>
		<button onclick="document.execCommand('underline', false, null)" >
		  下划线
		</button>
		<button onclick="document.execCommand('insertUnorderedList', false, null);" >
		  无序列表
		</button>
		<button onclick="document.execCommand('insertOrderedList', false, null);" >
		  有序列表
		</button>
		<button onclick="document.execCommand('createLink', false, prompt('请输入链接地址：'));" >
		  插入链接
		</button>
		<button onclick="document.execCommand('insertImage', false, prompt('请输入图片地址：'));">
		  插入图片
		</button>
    </div>
    <div id="editor" contenteditable="true"></div>
	
	<button onclick="save()">保存</button>
  </body>
  <script>
    // 获取相关元素
    const editor = document.querySelector("#editor");
	
	// let addedData = null	//	保存的数据
	let beforeKeywordData = null		//	键盘事件触发前的数据
	let signBegin = '<span contenteditable="false" class="add">'
	let signEnd = '</span>'

	function save() {
		const editor = document.getElementById('editor')
		
		//	清除之前的添加标记
		editor.innerHTML = editor.innerHTML.replaceAll(signBegin, '')
		editor.innerHTML = editor.innerHTML.replaceAll(signEnd, '')
		
		editor.innerHTML = signBegin + editor.innerHTML + signEnd
		// addedData = editor.innerHTML
		
		console.log('保存：', editor.innerHTML)
	}
	
	/**
	 * 设置参数
	 */
	function setParam() {
		// 获取Selection对象
		var selection = window.getSelection();

		// 判断是否有选区
		if (selection.rangeCount > 0) {
			let sign = '<p contenteditable="true" style="background-color: #00ffff; display: inline;">'
		  
		  // 获取当前选区的起点节点
		  var anchorNode = selection.anchorNode;
		  // 获取包含光标的最近的父元素
		  var parentElement = anchorNode.parentNode;

		  // 包含光标的最近的父元素
		  console.log("光标所在的元素：", parentElement);
		  
		  //	
		  if(parentElement.outerHTML.includes(sign)){
			  alert('当前内容已是参数')
			  
			  return
		  }
		}
		
		let range = window.getSelection().getRangeAt(0); // 获取当前选区范围
		let p = document.createElement("p"); // 创建加粗标签
		p.setAttribute("contenteditable", true); 
		p.setAttribute('style', 'background-color: #00ffff; display: inline;')
		p.textContent = range.toString(); // 将选中文本作为加粗标签的内容
		range.deleteContents(); // 删除选中文本
		range.insertNode(p); // 在选区范围内插入加粗标签
		range.setStartAfter(p);
		range.setEndAfter(p); // 设置光标位置
		window.getSelection().removeAllRanges();
		window.getSelection().addRange(range); // 重新设置选区范围		
	}
	
	// 监听keydown事件
	editor.addEventListener("keydown", function(event) {
		console.log(signBegin + '所在下标：', editor.innerHTML.indexOf(signBegin));
		
		// 获取Selection对象
		var selection = window.getSelection();
		
		// 判断是否有选区
		if (selection.rangeCount > 0) {
		  // 获取当前选区的范围
		  var range = selection.getRangeAt(0);
		
		  // 创建一个DocumentFragment对象，并将选区的内容克隆到其中
		  var fragment = range.cloneContents();
		
		  // 创建一个临时的div元素，将DocumentFragment对象的内容插入其中
		  var tempDiv = document.createElement("div");
		  tempDiv.appendChild(fragment);
		
		  // 获取临时div元素的innerHTML属性，即选区的HTML内容
		  var htmlContent = tempDiv.innerHTML;
		
		  console.log("选区的HTML内容：" + htmlContent);
		  
		  // 获取光标在选区中的偏移量
		  var offset = range.startOffset;
		  console.log("光标位置：" + offset);
		  				  
		  if(htmlContent != null && htmlContent.includes(signBegin)) {
					  alert('所选内容包含不可删除内容')
									
					  event.preventDefault()
		  } else {
			  if (event.key == 'Backspace') {
				  console.log('内容以' + signEnd + '结尾：', editor.innerHTML.endsWith(signEnd))
				  
				  if(editor.innerHTML.endsWith(signEnd)){
					  if(offset == 1){
						  alert('该内容不能删除')
										
						  event.preventDefault()
					  }
				  }
				  if(offset == 0){
					  alert('该内容不能删除')
									
					  event.preventDefault()
				  }
			  }
			  
			  if (event.key == 'Delete') {
				  if(offset == editor.innerHTML.indexOf(signBegin)){
					alert('该内容不能删除')
								
					event.preventDefault()
				  }
			  }
		  }
		}
	})
  </script>
</html>

